package face.pay.wxpay.service.impl;

import com.alibaba.fastjson.JSON;
import com.face.pay.IPayConfigServer;
import com.github.wxpay.sdk.WXPayUtil;
import face.pay.dao.CpnCardDetailInfoDao;
import face.pay.dao.EnterpriseInfoDao;
import face.pay.dao.StoreInfoDao;
import face.pay.dao.TerminalInfoDao;
import face.pay.entity.EnterpriseInfo;
import face.pay.entity.TerminalInfo;
import face.pay.util.HttpClientUtil;
import face.pay.util.MathUtil;
import face.pay.util.ResultMessage;
import face.pay.vo.VCpnCardDetail;
import face.pay.wxpay.service.IWxJsPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;


@Service
@Slf4j
public class WxJsPayServiceImpl implements IWxJsPayService {


    private static final String domain = "api.mch.weixin.qq.com";

    private static final String urlSuffix = "/pay/unifiedorder";


    @Value("${payApi.domain}")
    private String PayApidomain;


    @Autowired
    private EnterpriseInfoDao enterpriseInfoDao;


    @Autowired
    private IPayConfigServer iWxPayConfigServer;


    @Autowired
    private TerminalInfoDao terminalInfoDao;


    @Autowired
    private StoreInfoDao storeInfoDao;


    @Autowired
    public CpnCardDetailInfoDao cpnCardDetailInfoDao;


    /**
     * js扫码支付
     *
     * @param deviceId
     * @param openId
     * @param cpnId
     * @param total
     * @return
     */
    @Override
    public ResultMessage wxJsPay(String deviceId, String openId, String cpnId, String total, String act_total) {


        Double money = null;
        try {
            money = Double.parseDouble(total);
        } catch (NumberFormatException e) {
            log.info("微信扫码支付金额有误!!!  {}", e.toString());
            return ResultMessage.createFail("金额有误!");
        }

        if (money <= 0) {
            return ResultMessage.createFail("金额有误!");
        }


        Long total_fee = MathUtil.transForMoney(MathUtil.transScaleMoney(MathUtil.transForMoney(money)));


        Long act_fee = total_fee;
        if (StringUtils.isNotBlank(act_total)) {
            Double act_money = null;
            try {
                act_money = Double.parseDouble(act_total);
            } catch (NumberFormatException e) {
                log.info("微信扫码支付金额有误!!!  {}", e.toString());
                return ResultMessage.createFail("金额有误!");
            }

            if (act_money <= 0) {
                return ResultMessage.createFail("金额有误!");
            }

            act_fee = MathUtil.transForMoney(MathUtil.transScaleMoney(MathUtil.transForMoney(act_money)));
        }

        if (act_fee > total_fee) {
            return ResultMessage.createFail("折扣后金额不能大于原来金额");
        }


        TerminalInfo terminalInfo = this.terminalInfoDao.getByDeviceId(deviceId);
        if (StringUtils.isNotBlank(cpnId)) {
            String safe = payCardSafe(terminalInfo.getId(), Long.valueOf(cpnId), total_fee, act_fee);

            if (StringUtils.isNotBlank(safe)) {
                log.info("优惠金额不正确，中断支付");
                return ResultMessage.createFail("优惠金额不正确，中断支付");
            }
        }


        Map<String, Object> parmdata = new HashMap<>();

        parmdata.put("total_fee", total_fee);
        parmdata.put("act_fee", act_fee);
        parmdata.put("openid", openId);
        parmdata.put("device_id", deviceId);

        if (StringUtils.isNotBlank(cpnId)) {
            parmdata.put("cardDetailId", cpnId);
        }

        String s = null;
        ResultMessage rest = null;
        try {
            String jsondata = JSON.toJSONString(parmdata);
            log.info("微信jsapi支付推送到api>>>> 参数 {}", jsondata);
            s = HttpClientUtil.doPostJson(PayApidomain + "/wxJsPay/api/payorder", jsondata);
            rest = JSON.parseObject(s, ResultMessage.class);
            if (!Integer.valueOf(1).equals(rest.getCode())) {
                log.error("<<<<<<微信jsapi支付获取api结果失败 deviceId : {}  message: {}", deviceId, rest.getMessage());
                return ResultMessage.createFail(rest.getMessage());
            }
            log.info("微信jsapi支付推送到api获取结果<<<<< 参数 {}", rest.getData());
        } catch (Exception e) {
            log.warn("微信jsapi支付失败!!! {}", e.toString());
            return ResultMessage.createFail("支付失败!!!");
        }

        return ResultMessage.createSuccess(rest.getData());


    }


    /**
     * 获取优惠券详情
     *
     * @param deviceId
     * @param openId
     * @return
     */
    @Override
    public String getCpnInfo(String deviceId, String openId) {
        Map<String, String> map = new HashMap<>();
        map.put("device_id", deviceId);
        map.put("openid", openId);
        String jsondata = JSON.toJSONString(map);
        String s = HttpClientUtil.doPostJson(PayApidomain + "/cpn_card/queryData", jsondata);
        return s;
    }

    /**
     * 支付结果回调
     *
     * @param xmlData
     * @return
     */
    @Override
    public String payCallback(String xmlData) {
        log.info("接受到商家jsapi支付结果<<<<<<:{}", xmlData);

        Map<String, String> dataMap = null;
        try {
            dataMap = WXPayUtil.xmlToMap(xmlData);
        } catch (Exception e) {
            log.info("xml解析异常:{}", e.toString());
            return null;
        }

        if (WXPayUtil.isSuccess(dataMap)) {
            if ("SUCCESS".equalsIgnoreCase(dataMap.get("result_code"))) {
                String out_trade_no = dataMap.get("out_trade_no");
                log.info("支付成功 out_trade_no:{}", out_trade_no);
                return "<xml>" +
                        "   <return_code><![CDATA[SUCCESS]]></return_code>" +
                        "   <return_msg><![CDATA[OK]]></return_msg>" +
                        "</xml>";
            }

        }
        return null;

    }


    public String payCardSafe(Integer terminalId, Long cardDetailId, Long totalFee, Long actFee) {


        if (cardDetailId != null && cardDetailId > 0) {
            /**
             * 查询当前优惠券是否可以使用
             */
            VCpnCardDetail cardDetail = this.cpnCardDetailInfoDao.getVCpnById(cardDetailId);

            if (cardDetail == null) {
                log.error("未找到此次需要核销的优惠券或优惠券已被核销");
                return "未找到此次需要核销的优惠券或优惠券已被核销";
            } else {
                /**
                 * 卡券折扣
                 */
                Double c = MathUtil.sub(new Double(1), cardDetail.getDiscount());

                /**
                 * 应付款
                 */
                Long money = MathUtil.profit(totalFee, c);

                if (!(actFee.compareTo(money) == 0)) {
                    log.error("用户实际付款和优惠券折扣 不匹配");

                    return "用户实际付款和优惠券折扣 不匹配";

                }
            }
        }

        return null;
    }
}
